﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.ServiceLocation;
using Luna.WPF.ApplicationFramework;
using Caliburn.PresentationFramework.ApplicationModel;
using Caliburn.Core.Metadata;
using XWord.GUI.Presenters.Interface;
using System.ComponentModel;
using System.Collections;
using System.Reflection;
using XWord.WPF.ApplicationFramework;
using System.Windows;
using XWord.WPF.ApplicationFramework.Threads;
using XWord.Fundamental.Domain.Services;
using System.Threading;
using XWord.Fundamental.Domain;
using XWord.Common;

namespace XWord.GUI.Presenters.Words
{
    [Singleton("WordExplainsPresenter", typeof(WordExplainsPresenter))]
    public class WordExplainsPresenter : MultiPresenterManager, IDockablePresenter
    {
        private readonly IDockSitePresenter _dockSitePresenter;
        private readonly IServiceLocator _serviceLocator;
        public WordExplainsPresenter()
        {
            _serviceLocator = ServiceLocator.Current;
            _dockSitePresenter = _serviceLocator.GetInstance<IDockSitePresenter>();
            (_dockSitePresenter as PresenterBase).WasShutdown += new EventHandler(WordExplainsPresenter_WasShutdown);
            this.DisplayName = "单词详解";
        }

        void Current_Exit(object sender, ExitEventArgs e)
        {
            BinaryFormatterHelper.Serialize(BinaryFiles.WordExplains, ht);
        }

        void WordExplainsPresenter_WasShutdown(object sender, EventArgs e)
        {
            foreach (var item in _wordExplainList)
            {
                item.Update();
            }
        }

        public IWordBehavior WordBehavior { get; set; }

        protected override void OnInitialize()
        {
            base.OnInitialize();
            UIThread.BeginInvoke(() =>
            {
                Application.Current.Exit += new ExitEventHandler(Current_Exit);
            });

            this.Resgister();
            WordBehavior.WordEventHandler += new WordEventHandler(WordBehavior_WordEventHandler);
        }

        void WordBehavior_WordEventHandler(object sender, WordEventArgs args)
        {
            switch (args.Action)
            {
                case WordAction.Add:
                    foreach (var item in _wordExplainList)
                    {
                        item.AddWordAction(args.Word);
                    }
                    break;
                case WordAction.Remove:
                    foreach (var item in _wordExplainList)
                    {
                        item.RemoveWord(args.Word.Name);
                    }
                    break;
                case WordAction.SelectedItemChanged:
                    WordSelectedItemChanged(args.Word.Name);
                    break;
                default:
                    break;
            }
        }

        private bool _isShow;

        public void Resgister()
        {
            if (!IsInitialized)
            {
                _wordExplainList = _serviceLocator.GetAllInstances<IWordExplainPresenter>();

                var tempht = BinaryFormatterHelper.Deserialize<Hashtable>(BinaryFiles.WordExplains);

                if (tempht != null)
                {
                    ht = tempht;
                    foreach (var item in _wordExplainList)
                    {
                        item.Initialize();
                        (item as PresenterBase).Parent = this;
                        if (tempht != null && tempht[item.DisplayName] != null)
                        {
                            var itemHt = tempht[item.DisplayName] as Hashtable;
                            item.Index = itemHt["Index"] != null ? Convert.ToInt32(itemHt["Index"]) : item.Index;
                            item.OnService = itemHt["OnService"] != null ? Convert.ToBoolean(itemHt["OnService"]) : item.OnService;
                        }
                    }
                }

                _wordExplainList = _wordExplainList.OrderBy(e => e.Index);
                foreach (var item in _wordExplainList)
                {
                    item.PropertyChanged += new PropertyChangedEventHandler(wordExplainPresenter_PropertyChanged);
                    this.Presenters.Add(item);
                }
            }
        }

        private static PropertyInfo[] info = typeof(IWordExplainPresenter).GetProperties();

        private Hashtable ht = new Hashtable();

        void wordExplainPresenter_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var presenter = sender as IWordExplainPresenter;
            Hashtable presenterStore = null;
            if (!ht.ContainsKey(presenter.DisplayName))
            {
                ht[presenter.DisplayName] = new Hashtable();
            }
            presenterStore = ht[presenter.DisplayName] as Hashtable;
            if (info.Any(p => p.Name == e.PropertyName))
            {
                var propertyInfo = sender.GetType().GetProperty(e.PropertyName);
                var converter = TypeDescriptor.GetConverter(propertyInfo.PropertyType);
                var val = sender.GetType().GetProperty(e.PropertyName).GetValue(sender, null);
                presenterStore[e.PropertyName] = val;
            }
        }

        private IEnumerable<IWordExplainPresenter> _wordExplainList;

        void WordSelectedItemChanged(string word)
        {
            if (!_isShow)
            {
                this.Show();
                _isShow = true;
            }
            if (!string.IsNullOrEmpty(word))
            {
                foreach (var item in _wordExplainList)
                {
                    item.Name = word;
                    if (item.OnService)
                        item.WordChanged(word);
                }
            }
            UIThread.BeginInvoke(() =>
            {
                _serviceLocator.GetInstance<IDockSitePresenter>().Activate(this);
            });

        }

        public IWordExplorerPresenter WordExplorerPresenter { get; set; }

        public virtual void Show()
        {
            _dockSitePresenter.Show(this);
        }

        public void ShowRibbon()
        {
            throw new NotImplementedException();
        }

        public void ShowManageDilog()
        {
            var presenter = _serviceLocator.GetInstance<DictManagerPresenter>();
            if (!presenter.IsInitialized)
            {
                presenter.PresenterList = this.Presenters as IList;
            }
            _serviceLocator.GetInstance<IWindowManager>()
               .ShowDialog(presenter, null, ExecuteShutdownModel);
        }
    }
}
